﻿using Newtonsoft.Json;
using Sustainalytics.Claims;
using Sustainalytics.Entities;
using Sustainalytics.OAuth.Services.Common;
using Sustainalytics.Portfolios.BL;
using Sustainalytics.Portfolios.BL.Model;
using Sustainalytics.Portfolios.Service.Models;
using Sustainalytics.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace Sustainalytics.Portfolios.Service.Controllers
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [LogControllerFilter(true, true, false)]
    [RoutePrefix("api/v1/subscribetoportfolio")]
    public class SubscribeToPortfolioController : ApiController
    {
        private static IClaimsChecker _claimsChecker;
        private readonly IPortfolioReadHandler _portfolioManager;
        private readonly ISubscribeToPortfolioManagement _subscribeManager;
        private readonly PortfolioUserClaimsProcessor _userClaimsProcessor;

        // TODO: validate that all endpoints are used
        public SubscribeToPortfolioController(
            ISubscribeToPortfolioManagement subscribeManager,
            IPortfolioReadHandler portfolioManager,
            IClaimsChecker claimsChecker,
            PortfolioUserClaimsProcessor userClaimsProcessor)
        {
            _claimsChecker = claimsChecker;
            this._userClaimsProcessor = userClaimsProcessor;
            _subscribeManager = subscribeManager;
            _portfolioManager = portfolioManager;
        }

        [Route("{id}")]
        public HttpResponseMessage Delete([FromUri] Guid id, Guid userId, Guid accountId)
        {
            _subscribeManager.DeleteSubscribeToPortfolio(id);
            return Request.CreateResponse(HttpStatusCode.OK);
        }

        [Route("")]
        public HttpResponseMessage Get([FromUri] Guid userId, Guid accountId, bool getAllPortfolios = false, bool onlyAutomaticSystemPortfolios = false)
        {
            var userClaims = _userClaimsProcessor.GetPortfolioClaims();

            List<Portfolio> portfolioList;
            if (getAllPortfolios)
            {
                var filter = new PortfolioFilter
                {
                    SharingStatus = PortfolioSharingStatus.All,
                    AddedByUserId = userClaims.UserId,
                    AccountId = userClaims.AccountId,
                    PortfolioType = PortfolioTypes.All
                };

                portfolioList = _portfolioManager.GetPortfolios(filter).ToList();
                if (onlyAutomaticSystemPortfolios)
                    portfolioList = portfolioList.Where(x => x.GetType() != typeof(ManualSystemPortfolio)).ToList();

                return Request.CreateResponse(
                    HttpStatusCode.OK,
                    new { portfolioList = portfolioList.ConvertAll(PortfolioDto.CreateWithNameIdUserIdAndIsAutomatic) });
            }

            var subscriptionList = _subscribeManager.GetSubscriptions(userClaims);

            var subscriptionListDto = new List<SubscribeToPortfolioDto>();

            var portfolioIds = subscriptionList.SelectMany(x => x.PortfolioIds).ToList();
            if (portfolioIds.IsNullOrEmpty())
            {
                return Request.CreateResponse(HttpStatusCode.OK, new { subscriptionListDto });
            }

            portfolioList = _portfolioManager.GetPortfoliosByIds(portfolioIds, userClaims).ToList();
            subscriptionListDto =
                subscriptionList.Select(p => SubscribeToPortfolioDto.CreateFull(p, portfolioList)).ToList();

            // add "all companies" special portfolio:
            if (portfolioIds.Contains(Guid.Empty))
            {
                subscriptionListDto[0].PortfolioList.Add(
                    new PortfolioSubscribeDto() { PortfolioId = Guid.Empty, IsMyPortfolio = true });
            }

            return Request.CreateResponse(HttpStatusCode.OK, new { subscriptionListDto });
        }

        // used to Enable/Disable the subscription
        [Route("{id}")]
        public HttpResponseMessage Patch([FromUri] Guid id, Guid userId, Guid accountId, bool status)
        {
            _subscribeManager.UpdateSubscribeState(id, status);

            return Request.CreateResponse(HttpStatusCode.OK);
        }

        [Route("")]
        public HttpResponseMessage Post([FromBody] object subscriptionDto)
        {
            return UpdateSubscription(subscriptionDto, true);
        }

        [Route("")]
        public HttpResponseMessage Put([FromBody] object subscriptionDto)
        {
            return UpdateSubscription(subscriptionDto, false);
        }

        private HttpResponseMessage UpdateSubscription(object subscriptionDto, bool addNew)
        {
            var subscription = JsonConvert.DeserializeObject<SubscribeToPortfolio>(subscriptionDto.ToString());

            if (subscription == null)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }

            if (addNew)
            {
                _subscribeManager.AddSubscribeToPortfolio(subscription);
            }
            else
            {
                _subscribeManager.UpdateSubscribeToPortfolio(subscription);
            }

            return Request.CreateResponse(HttpStatusCode.OK);
        }
    }
}
